import os
import time

from natsort import ns, natsorted
import cv2
from skimage.metrics import structural_similarity as ssim

from package.base_demo import list_to_str,write_file_from_get_frame
from package.hash_compare import *
import shutil


class GetPicture():

    #获取帧数的，用于计算视频时间
    i=0
    iooo = 0
    fps = None
    frame1 = None

    def __init__(self, n1, n2, retvalB, retvalR, retvalG, sim, xsdnmaa, timefsec, videopath):
        self.n1 = int(n1)
        self.n2 = int(n2)
        self.retvalB = float(retvalB)
        self.retvalR = float(retvalR)
        self.retvalG = float(retvalG)
        self.sim = float(sim)
        self.xsdnmaa = int(xsdnmaa)
        self.xlcs = int(xsdnmaa)
        self.xlcsp = int(xsdnmaa) + 1
        self.timefsec = timefsec
        self.videopath = videopath
        self.image_quality = 60

    # 这是毫秒，转换为时间形式的。
    def seconnds_2_time(self, seconds):
        h = int(seconds / 3600)
        if h >= 0 and h < 10:
            H = "0" + str(h)
        else:
            H = str(h)
        a = seconds % 3600
        m = int(a / 60)
        if m >= 0 and m < 10:
            M = "0" + str(m)
        else:
            M = str(m)
        s = a % 60
        if s >= 0 and s < 10:
            S = "0" + str(s)
        else:
            S = str(s)
        abnm = H + ":" + M + ":" + S
        print(str(abnm))
        return H + "-" + M + "-" + S

    def transfer_millsec(self, framenum, fps):

        millsec = int(framenum / fps) * 1  # 多少秒,#多少毫秒
        return millsec

    # 保存函数
    def sa_bc(self, frame, j, test_num):
        self.frame1 = frame

        # 2代表的是压缩保存
        if int(test_num) == 2:
            # 保存为帧截图，就是将帧转换为时间的形式
            video_time_seconds = self.transfer_millsec(self.i, self.fps)
            video_time_moment = self.seconnds_2_time(video_time_seconds)

            h, w = frame.shape[:2]
            # 就是处理之后，再写入保存
            image_resize = cv2.resize(frame, dsize=(int(w // 1.7), int(h // 1.7)))
            # + "_"+str(video_time_moment)
            cv2.imwrite('./output/' + str(self.iooo) + '/' + str(j) + "[" + str(video_time_moment) + "].jpg",
                        image_resize,
                        [int(cv2.IMWRITE_JPEG_QUALITY), self.image_quality])
        else:
            # 这里，0跟1都是正常保存的
            cv2.imwrite('./output/' + str(self.iooo) + '/' + str(j) + ".jpg", frame)
            # 更新frame1
        # self.frame1 = frame
        print(f'提前结束，已保存')


    def detect_save_image(self, test_img_frame, num, test_num):
        try:
            if int(num) > 1:
                img1 = self.frame1
                img2 = test_img_frame

                hist1B = cv2.calcHist([img1], [0], None, [256], [0, 255])
                hist2B = cv2.calcHist([img2], [0], None, [256], [0, 255])
                retvalB = cv2.compareHist(hist1B, hist2B, cv2.HISTCMP_CORREL)

                # 1的时候，才提取保存输出
                if int(test_num) == 1 or int(test_num) == 2:
                    if retvalB < self.retvalB:
                        self.sa_bc(test_img_frame, num, test_num)
                        return

                hist1G = cv2.calcHist([img1], [1], None, [256], [0, 255])
                hist2G = cv2.calcHist([img2], [1], None, [256], [0, 255])
                retvalG = cv2.compareHist(hist1G, hist2G, cv2.HISTCMP_CORREL)

                if int(test_num) == 1 or int(test_num) == 2:
                    if retvalG < self.retvalG:
                        self.sa_bc(test_img_frame, num, test_num)
                        return

                hist1R = cv2.calcHist([img1], [2], None, [256], [0, 255])
                hist2R = cv2.calcHist([img2], [2], None, [256], [0, 255])
                retvalR = cv2.compareHist(hist1R, hist2R, cv2.HISTCMP_CORREL)

                if int(test_num) == 1 or int(test_num) == 2:
                    if retvalR < self.retvalR:
                        self.sa_bc(test_img_frame, num, test_num)
                        return

                image1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)  # 将图像转换为灰度图
                image2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)  # 将图像转换为灰度图
                sim = ssim(image1, image2)

                if int(test_num) == 1 or int(test_num) == 2:
                    if sim < self.sim:
                        self.sa_bc(test_img_frame, num, test_num)
                        return

                hash1 = aHash(img1, self.xlcs)
                hash2 = aHash(img2, self.xlcs)
                n1 = cmpHash(hash1, hash2)

                if int(test_num) == 1 or int(test_num) == 2:
                    if n1 > self.n1:
                        self.sa_bc(test_img_frame, num, test_num)
                        return

                hash1 = dHash(img1, self.xlcs, self.xlcsp)
                hash2 = dHash(img2, self.xlcs, self.xlcsp)
                n2 = cmpHash(hash1, hash2)

                if int(test_num) == 1 or int(test_num) == 2:
                    if n2 > self.n2:
                        self.sa_bc(test_img_frame, num, test_num)
                        return

                if int(test_num) == 0:
                    print('retvalB', retvalB)
                    print('retvalG', retvalG)
                    print('retvalR', retvalR)
                    print(f'skimage结构相似度为:{sim},\n均值哈希算法相似度：{n1}\n差值哈希算法相似度：{n2}')

                if n1 < self.n1 and n2 < self.n2 and \
                        (retvalB > self.retvalB and retvalR > self.retvalR and retvalG > self.retvalG and
                         sim > self.sim):
                    pass
                else:

                    self.sa_bc(test_img_frame, num, test_num)

        except Exception as e:
            print(e)

    # 调式时的清空操作
    # 执行前，先删除文件夹里面的内容
    @classmethod
    def delete_template_file(cls):
        pathy = './output/1'
        if os.path.exists(pathy):
            shutil.rmtree(pathy)
            print('存在首文件夹，清空')
            time.sleep(2)

    def get_picture(self, test_num):
        if int(test_num) == 0 or int(test_num) == 2:
            self.delete_template_file()

        pathy = self.videopath
        # 给文件夹的文件进行排序
        files = os.listdir(self.videopath)
        files = natsorted(files, alg=ns.PATH)

        #这里写一个保存文件的函数方法
        liststr_to_save=list_to_str(files)
        write_file_from_get_frame(str(pathy)+"_重命名文件记录.txt",liststr_to_save)

        if not os.path.exists(os.getcwd() + "/output"):
            print("输出文件夹不存在，帮你自动创建好了")
            print("==================================")
            os.mkdir("./output")

        exte_type = '.mp4'

        for filename in files:
            self.iooo = self.iooo + 1
            exte_nam = os.path.splitext(filename)[1]
            print('后缀名为：' + str(exte_nam))

            if exte_nam:
                print("后缀名存在")
                if str(exte_type) == str(exte_nam):
                    filename0 = os.path.splitext(filename)[0]
                    filename1 = os.path.splitext(filename)[1]

                    # 重命名视频文件为1
                    aab = pathy + '/' + filename
                    newname = pathy + '/' + str(self.iooo) + str(filename1)
                    os.rename(aab, newname)

                    # 这个是给图片文件夹重命名回来的。
                    wjjbc = filename0

                    if not os.path.exists(os.getcwd() + "/output/" + str(self.iooo)):
                        print("输出文件夹不存在，帮你自动创建好了")
                        print("==================================")
                        os.mkdir("./output/" + str(self.iooo))

                    videoCapture = cv2.VideoCapture(newname)

                    # 获取帧速率
                    self.fps = videoCapture.get(cv2.CAP_PROP_FPS)
                    timeF = int(self.fps) * int(self.timefsec)

                    # 读帧
                    success, frame = videoCapture.read()

                    self.i = 0

                    j = 0

                    while success:
                        self.i = self.i + 1
                        if self.i % timeF == 0:
                            j = j + 1
                            if j == 1:

                                self.sa_bc(frame, j, test_num)


                            if j != 1:
                                self.detect_save_image(frame, j, test_num)
                                print('compare image:', self.i)

                        # 这个是不断获取新的frame
                        success, frame = videoCapture.read()

                    # 销毁所有的数据
                    # 释放资源，解除占用
                    videoCapture.release()
                    cv2.destroyAllWindows()
                    # 然后再重命名回来
                    # 这应该是，如果正在读取，就不能重命名
                    os.rename(newname, aab)
                    os.rename('./output/' + str(self.iooo), './output/' + str(wjjbc))



if __name__ == '__main__':
    pass
